<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>花花直播助手歌词显示器</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Microsoft YaHei', 'Segoe UI', sans-serif;
        }
        
        :root {
            --primary: #ff00cc;
            --secondary: #00ccff;
            --accent: #ffff00;
            --bg: rgba(10, 5, 20, 0.85);
            --text: #ffffff;
            --progress: #ff00cc;
            --bg-opacity: 0.85;
        }
        
        body {
            background: transparent !important;
            overflow: hidden;
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            color: var(--text);
        }
        
        .container {
            position: relative;
            width: 100%;
            max-width: 1200px;
            height: 90%;
            display: flex;
            flex-direction: column;
            border-radius: 20px;
            overflow: hidden;
            background: rgba(10, 5, 20, var(--bg-opacity));
            box-shadow: 
                0 0 30px rgba(255, 0, 255, 0.6),
                inset 0 0 20px rgba(255, 255, 255, 0.2);
            backdrop-filter: blur(10px);
            transition: background 0.3s ease;
        }
        
        /* 顶部标题栏 */
        .header {
            padding: 12px 25px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            background: linear-gradient(90deg, rgba(255,0,204,0.3), rgba(0,204,255,0.3));
            border-bottom: 1px solid rgba(255,255,255,0.1);
            z-index: 20;
            overflow: hidden;
        }
        
        .logo {
            display: flex;
            align-items: center;
            gap: 12px;
            max-width: 70%;
        }
        
        .logo-icon {
            font-size: 2rem;
            color: var(--primary);
            animation: pulse 2s infinite alternate;
            flex-shrink: 0;
        }
        
        .title-container {
            flex: 1;
            min-width: 0;
            overflow: hidden;
        }
        
        /* 标题滚动效果调整 - 12字以内完整显示，超过则循环滚动 */
        .title {
            font-size: 1.8rem;
            font-weight: 700;
            background: linear-gradient(90deg, var(--primary), var(--secondary));
            -webkit-background-clip: text;
            background-clip: text;
            color: transparent;
            white-space: nowrap;
            display: inline-block;
            padding-right: 100%;
            animation: scrollTitle 15s linear infinite;
            max-width: 100%;
            overflow: visible;
        }
        
        .title.no-scroll {
            animation: none;
            padding-right: 0;
            display: block;
            text-overflow: unset;
            width: 100%;
            text-align: center;
        }
        
        .status-indicator {
            display: flex;
            align-items: center;
            gap: 8px;
            padding: 6px 15px;
            background: rgba(0, 0, 0, 0.5);
            border-radius: 20px;
            font-size: 1rem;
            white-space: nowrap;
            min-width: 140px;
        }
        
        .status-dot {
            width: 10px;
            height: 10px;
            border-radius: 50%;
            background: #55ff55;
            box-shadow: 0 0 12px #55ff55;
        }
        
        /* 主内容区 */
        .main-content {
            display: flex;
            flex: 1;
            padding: 15px;
            gap: 15px;
            z-index: 15;
            position: relative;
        }
        
        /* 左侧播放列表 */
        .playlist-container {
            flex: 1;
            padding: 15px;
            border-right: 1px solid rgba(255,255,255,0.1);
            overflow-y: auto;
            max-height: 100%;
        }
        
        .playlist-title {
            font-size: 1.5rem;
            margin-bottom: 15px;
            padding-bottom: 8px;
            border-bottom: 2px solid var(--primary);
            color: var(--primary);
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        
        .playlist {
            list-style: none;
        }
        
        .playlist-item {
            padding: 12px;
            margin-bottom: 10px;
            background: rgba(255, 255, 255, 0.05);
            border-radius: 12px;
            display: flex;
            align-items: center;
            gap: 12px;
            transition: all 0.3s ease;
            cursor: pointer;
        }
        
        .playlist-item:hover {
            background: rgba(255, 255, 255, 0.1);
        }
        
        .playlist-item.active {
            background: linear-gradient(90deg, rgba(255,0,204,0.3), rgba(0,0,0,0.3));
            border-left: 3px solid var(--primary);
            transform: translateX(5px);
        }
        
        .song-number {
            font-size: 1.2rem;
            font-weight: bold;
            color: var(--secondary);
            min-width: 25px;
        }
        
        .song-info {
            flex: 1;
            min-width: 0;
        }
        
        .song-title {
            font-size: 1.2rem;
            font-weight: bold;
            margin-bottom: 4px;
            color: var(--text);
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        
        .song-artist {
            font-size: 1rem;
            color: rgba(255, 255, 255, 0.7);
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        
        .song-duration {
            font-size: 1rem;
            color: var(--accent);
            min-width: 50px;
            text-align: right;
        }
        
        /* 右侧歌词显示 */
        .lyrics-container {
            flex: 2;
            display: flex;
            flex-direction: column;
            padding: 15px;
        }
        
        .current-song {
            display: flex;
            align-items: center;
            gap: 15px;
            margin-bottom: 20px;
            padding: 12px;
            background: rgba(255, 255, 255, 0.05);
            border-radius: 15px;
        }
        
        .album-art {
            width: 90px;
            height: 90px;
            border-radius: 10px;
            background: linear-gradient(45deg, var(--primary), var(--secondary));
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 2.2rem;
            color: white;
            box-shadow: 0 0 20px rgba(255, 0, 255, 0.4);
            overflow: hidden;
            flex-shrink: 0;
        }
        
        .album-art img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }
        
        .current-song-info {
            flex: 1;
            min-width: 0;
            overflow: hidden;
        }
        
        .current-title {
            font-size: 1.8rem;
            font-weight: bold;
            margin-bottom: 8px;
            color: var(--text);
            text-shadow: 0 0 8px rgba(255, 255, 255, 0.4);
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            max-width: 100%;
        }
        
        .current-artist {
            font-size: 1.3rem;
            color: var(--secondary);
            margin-bottom: 10px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            max-width: 100%;
        }
        
        .lyrics-display {
            flex: 1;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            text-align: center;
            padding: 20px;
            background: rgba(0, 0, 0, 0.3);
            border-radius: 20px;
            position: relative;
            overflow: hidden;
        }
        
        .previous-line, .next-line {
            font-size: 1.6rem;
            color: rgba(255, 255, 255, 0.6);
            margin: 12px 0;
            max-width: 90%;
            text-shadow: 0 0 6px rgba(255, 255, 255, 0.3);
            transition: all 0.3s ease;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            width: 100%;
        }
        
        .current-line {
            font-size: 2.8rem;
            font-weight: 800;
            line-height: 1.3;
            background: linear-gradient(90deg, 
                #ff0000, #ff8000, #ffff00, #80ff00,
                #00ff00, #00ff80, #00ffff, #0080ff, 
                #0000ff, #8000ff, #ff00ff, #ff0080);
            background-size: 300% 100%;
            -webkit-background-clip: text;
            background-clip: text;
            color: transparent;
            animation: gradient-scroll 8s linear infinite;
            padding: 15px 30px;
            margin: 15px 0;
            border-radius: 15px;
            position: relative;
            text-shadow: 0 0 15px rgba(255, 255, 255, 0.7);
            max-width: 90%;
            transition: all 0.3s ease;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            width: 100%;
        }
        
        .current-line::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0, 0, 0, 0.6);
            z-index: -1;
            border-radius: 15px;
            filter: blur(15px);
        }
        
        .progress-container {
            width: 90%;
            height: 10px;
            background: rgba(255, 255, 255, 0.15);
            border-radius: 8px;
            margin: 25px auto 15px;
            position: relative;
            overflow: hidden;
            box-shadow: 0 0 12px rgba(0, 0, 0, 0.5);
        }
        
        .progress-bar {
            height: 100%;
            width: 0;
            background: linear-gradient(90deg, var(--primary), var(--secondary));
            border-radius: 8px;
            position: relative;
            transition: width 0.2s linear;
        }
        
        .progress-bar::after {
            content: '';
            position: absolute;
            right: -10px;
            top: -5px;
            width: 20px;
            height: 20px;
            background: #ffffff;
            border-radius: 50%;
            box-shadow: 0 0 20px #00ffff;
            animation: pulse 1.5s infinite alternate;
        }
        
        .time-info {
            display: flex;
            justify-content: space-between;
            width: 90%;
            font-size: 1.1rem;
            color: rgba(255, 255, 255, 0.8);
            white-space: nowrap;
        }
        
        /* 音频频谱可视化 */
        .audio-spectrum-container {
            width: 90%;
            height: 120px;
            margin: 20px auto 10px;
            display: flex;
            justify-content: center;
            align-items: center;
            position: relative;
            border-radius: 15px;
            overflow: hidden;
            background: rgba(0, 0, 0, 0.2);
        }
        
        #audioSpectrum {
            width: 100%;
            height: 100%;
        }
        
        /* 粒子效果 - 轻量级 */
        .particle {
            position: absolute;
            border-radius: 50%;
            background: rgba(255, 255, 255, 0.7);
            pointer-events: none;
            z-index: 1;
            animation: float 8s ease-in-out infinite;
        }
        
        /* 背景透明度控制面板 */
        .controls-panel {
            position: absolute;
            top: 15px;
            right: 15px;
            background: rgba(0, 0, 0, 0.7);
            border-radius: 15px;
            padding: 15px;
            z-index: 100;
            display: flex;
            flex-direction: column;
            gap: 12px;
            backdrop-filter: blur(5px);
            border: 1px solid rgba(255, 255, 255, 0.1);
            max-width: 300px;
        }
        
        .panel-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 5px;
        }
        
        .panel-title {
            font-size: 1.2rem;
            font-weight: bold;
            color: var(--primary);
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            max-width: 80%;
        }
        
        .close-btn {
            background: none;
            border: none;
            color: white;
            font-size: 1.2rem;
            cursor: pointer;
            width: 30px;
            height: 30px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            flex-shrink: 0;
        }
        
        .close-btn:hover {
            background: rgba(255, 255, 255, 0.1);
        }
        
        .control-group {
            display: flex;
            flex-direction: column;
            gap: 8px;
        }
        
        .control-label {
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        
        .label-text {
            font-size: 0.9rem;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            max-width: 70%;
        }
        
        .value-display {
            font-size: 0.9rem;
            background: rgba(255, 255, 255, 0.1);
            padding: 2px 8px;
            border-radius: 10px;
            min-width: 40px;
            text-align: center;
            white-space: nowrap;
        }
        
        .slider {
            -webkit-appearance: none;
            width: 100%;
            height: 8px;
            border-radius: 5px;
            background: rgba(255, 255, 255, 0.1);
            outline: none;
        }
        
        .slider::-webkit-slider-thumb {
            -webkit-appearance: none;
            width: 20px;
            height: 20px;
            border-radius: 50%;
            background: var(--primary);
            cursor: pointer;
            box-shadow: 0 0 10px var(--primary);
        }
        
        /* 频谱模式控制按钮 */
        .spectrum-mode-controls {
            display: flex;
            gap: 8px;
            margin-top: 5px;
        }
        
        .spectrum-mode-btn {
            flex: 1;
            background: rgba(0, 0, 0, 0.5);
            border: none;
            color: white;
            padding: 6px 0;
            border-radius: 15px;
            font-size: 0.85rem;
            cursor: pointer;
            transition: all 0.2s ease;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        
        .spectrum-mode-btn:hover {
            background: rgba(255, 0, 204, 0.5);
        }
        
        .spectrum-mode-btn.active {
            background: var(--primary);
            box-shadow: 0 0 10px var(--primary);
        }
        
        .obs-tips {
            background: rgba(255, 0, 204, 0.15);
            border-left: 3px solid var(--primary);
            padding: 10px;
            border-radius: 0 8px 8px 0;
            font-size: 0.85rem;
            margin-top: 10px;
        }
        
        .obs-tips h4 {
            margin-bottom: 5px;
            color: var(--accent);
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        
        .obs-tips p {
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        
        .obs-tips code {
            background: rgba(0, 0, 0, 0.3);
            padding: 2px 6px;
            border-radius: 4px;
            font-family: monospace;
            white-space: nowrap;
        }
        
        /* 连接状态指示 */
        .connection-status {
            position: absolute;
            bottom: 15px;
            right: 15px;
            padding: 8px 15px;
            background: rgba(0, 0, 0, 0.5);
            border-radius: 20px;
            font-size: 1rem;
            display: flex;
            align-items: center;
            gap: 8px;
            z-index: 100;
            white-space: nowrap;
            max-width: 80%;
        }
        
        /* 媒体显示区域 */
        .media-container {
            position: absolute;
            z-index: 10;
            border-radius: 10px;
            overflow: hidden;
            box-shadow: 0 0 20px rgba(0, 0, 0, 0.6);
            transition: all 0.3s ease;
            border: 2px solid var(--primary);
            background: rgba(0, 0, 0, 0.6);
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            width: 200px;
            height: 150px;
            /* 定位到歌词区域左下角 */
            left: 20px;
            bottom: 20px;
        }
        
        .media-container img {
            max-width: 100%;
            max-height: 100%;
            display: block;
            object-fit: contain;
        }
        
        .media-controls {
            position: absolute;
            bottom: 5px;
            left: 0;
            right: 0;
            background: rgba(0, 0, 0, 0.7);
            padding: 5px;
            display: flex;
            justify-content: center;
            gap: 5px;
            opacity: 0;
            transition: opacity 0.3s ease;
        }
        
        .media-container:hover .media-controls {
            opacity: 1;
        }
        
        .media-controls button {
            background: var(--primary);
            color: white;
            border: none;
            padding: 3px 8px;
            border-radius: 5px;
            cursor: pointer;
            font-size: 0.8rem;
        }
        
        /* 开关样式 */
        .switch {
            position: relative;
            display: inline-block;
            width: 50px;
            height: 24px;
        }
        
        .switch input {
            opacity: 0;
            width: 0;
            height: 0;
        }
        
        .slider-switch {
            position: absolute;
            cursor: pointer;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: #ccc;
            transition: .4s;
            border-radius: 24px;
        }
        
        .slider-switch:before {
            position: absolute;
            content: "";
            height: 16px;
            width: 16px;
            left: 4px;
            bottom: 4px;
            background-color: white;
            transition: .4s;
            border-radius: 50%;
        }
        
        input:checked + .slider-switch {
            background-color: var(--primary);
        }
        
        input:checked + .slider-switch:before {
            transform: translateX(26px);
        }
        
        /* 文件上传区域 */
        .upload-area {
            border: 2px dashed rgba(255, 255, 255, 0.3);
            border-radius: 10px;
            padding: 15px;
            text-align: center;
            cursor: pointer;
            transition: all 0.3s ease;
            margin-top: 10px;
            background: rgba(0, 0, 0, 0.2);
        }
        
        .upload-area:hover {
            border-color: var(--primary);
            background: rgba(255, 0, 204, 0.1);
        }
        
        .upload-area i {
            font-size: 2rem;
            color: var(--secondary);
            margin-bottom: 10px;
            display: block;
        }
        
        .upload-area p {
            font-size: 0.9rem;
            color: rgba(255, 255, 255, 0.7);
        }
        
        .upload-btn {
            display: inline-block;
            margin-top: 10px;
            padding: 6px 15px;
            background: var(--primary);
            color: white;
            border-radius: 20px;
            cursor: pointer;
            font-size: 0.9rem;
        }
        
        /* 动画效果 */
        @keyframes gradient-scroll {
            0% { background-position: 0% 50%; }
            100% { background-position: 100% 50%; }
        }
        
        @keyframes pulse {
            0% { box-shadow: 0 0 5px #00ffff; transform: scale(1); }
            100% { box-shadow: 0 0 25px #00ffff, 0 0 40px #ff00ff; transform: scale(1.1); }
        }
        
        @keyframes float {
            0% { transform: translate(0, 0) scale(1); opacity: 0.7; }
            50% { transform: translate(20px, -20px) scale(0.8); }
            100% { transform: translate(0, 0) scale(1); opacity: 0; }
        }
        
        @keyframes scrollTitle {
            0% { transform: translateX(0); }
            100% { transform: translateX(-100%); }
        }
        
        /* 响应式调整 */
        @media (max-width: 900px) {
            .main-content {
                flex-direction: column;
            }
            
            .playlist-container {
                border-right: none;
                border-bottom: 1px solid rgba(255,255,255,0.1);
                max-height: 250px;
            }
            
            .current-line {
                font-size: 2.2rem;
                padding: 12px 20px;
            }
            
            .previous-line, .next-line {
                font-size: 1.4rem;
            }
            
            .current-title {
                font-size: 1.5rem;
            }
            
            .current-artist {
                font-size: 1.1rem;
            }
            
            .audio-spectrum-container {
                height: 80px;
            }
            
            .controls-panel {
                top: 5px;
                right: 5px;
                padding: 10px;
                max-width: 250px;
            }
            
            .title-container {
                max-width: 60%;
            }
            
            .media-container {
                bottom: 10px;
                left: 10px;
                max-width: 150px;
                max-height: 120px;
            }
        }
        
        @media (max-width: 600px) {
            .title-container {
                max-width: 50%;
            }
            
            .status-indicator {
                min-width: 120px;
                font-size: 0.9rem;
                padding: 4px 10px;
            }
            
            .media-container {
                width: 150px;
                height: 120px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <!-- 顶部标题栏 -->
        <div class="header">
            <div class="logo">
                <div class="logo-icon">♪</div>
                <div class="title-container">
                    <div class="title" id="mainTitle">花花直播助手歌词显示器</div>
                </div>
            </div>
            <div class="status-indicator">
                <div class="status-dot" id="statusDot"></div>
                <span id="statusText">正在初始化...</span>
            </div>
        </div>
        
        <!-- 主内容区 -->
        <div class="main-content">
            <!-- 左侧播放列表 -->
            <div class="playlist-container">
                <h2 class="playlist-title">播放列表</h2>
                <ul class="playlist" id="playlist">
                    <li class="playlist-item">
                        <div class="song-number">1</div>
                        <div class="song-info">
                            <div class="song-title">正在加载播放列表...</div>
                            <div class="song-artist">请稍候</div>
                        </div>
                        <div class="song-duration">0:00</div>
                    </li>
                </ul>
            </div>
            
            <!-- 右侧歌词显示 -->
            <div class="lyrics-container">
                <div class="current-song">
                    <div class="album-art">
                        <div>♪</div>
                    </div>
                    <div class="current-song-info">
                        <div class="current-title" id="currentSongTitle">等待歌曲信息</div>
                        <div class="current-artist" id="currentSongArtist">等待歌手信息</div>
                        <div class="time-info">
                            <span id="currentTime">0:00</span>
                            <span id="totalTime">0:00</span>
                        </div>
                    </div>
                </div>
                
                <div class="lyrics-display">
                    <div class="previous-line" id="previousLine"></div>
                    <div class="current-line" id="currentLine">正在连接歌词服务...</div>
                    <div class="next-line" id="nextLine"></div>
                    
                    <div class="progress-container">
                        <div class="progress-bar" id="progressBar"></div>
                    </div>
                    
                    <div class="time-info">
                        <span id="progressTime">0:00</span>
                        <span id="remainingTime">0:00</span>
                    </div>
                    
                    <!-- 音频频谱可视化 -->
                    <div class="audio-spectrum-container">
                        <canvas id="audioSpectrum"></canvas>
                    </div>
                </div>
            </div>
        </div>
        
        <!-- 背景透明度控制面板 -->
        <div class="controls-panel">
            <div class="panel-header">
                <div class="panel-title">OBS控制面板</div>
                <button class="close-btn" id="closePanel">×</button>
            </div>
            
            <div class="control-group">
                <div class="control-label">
                    <span class="label-text">背景透明度</span>
                    <span class="value-display" id="opacityValue">85%</span>
                </div>
                <input type="range" min="0" max="100" value="85" class="slider" id="opacitySlider">
            </div>
            
            <div class="control-group">
                <div class="control-label">
                    <span class="label-text">频谱强度</span>
                    <span class="value-display" id="spectrumValue">70%</span>
                </div>
                <input type="range" min="10" max="100" value="70" class="slider" id="spectrumSlider">
            </div>
            
            <div class="control-group">
                <div class="control-label">
                    <span class="label-text">频谱模式</span>
                </div>
                <div class="spectrum-mode-controls">
                    <button class="spectrum-mode-btn active" data-mode="bars">柱状</button>
                    <button class="spectrum-mode-btn" data-mode="wave">波浪</button>
                    <button class="spectrum-mode-btn" data-mode="circle">圆形</button>
                </div>
            </div>
            
            <div class="control-group">
                <div class="control-label">
                    <span class="label-text">媒体宽度</span>
                    <span class="value-display" id="mediaWidthValue">200px</span>
                </div>
                <input type="range" min="50" max="500" value="200" class="slider" id="mediaWidthSlider">
            </div>
            
            <div class="control-group">
                <div class="control-label">
                    <span class="label-text">媒体高度</span>
                    <span class="value-display" id="mediaHeightValue">150px</span>
                </div>
                <input type="range" min="50" max="500" value="150" class="slider" id="mediaHeightSlider">
            </div>
            
            <div class="control-group">
                <div class="control-label">
                    <span class="label-text">媒体URL</span>
                </div>
                <input type="text" id="mediaUrlInput" placeholder="输入图片/GIF URL">
                <button id="loadMediaBtn">加载媒体</button>
                <button id="clearMediaBtn" style="background: #ff5555;">清除媒体</button>
            </div>
            
            <div class="control-group">
                <div class="control-label">
                    <span class="label-text">显示媒体外框</span>
                    <label class="switch">
                        <input type="checkbox" id="frameToggle" checked>
                        <span class="slider-switch"></span>
                    </label>
                </div>
            </div>
            
            <!-- 图片上传区域 -->
            <div class="control-group">
                <div class="control-label">
                    <span class="label-text">上传图片/GIF</span>
                </div>
                <div class="upload-area" id="uploadArea">
                    <i>📁</i>
                    <p>拖放图片/GIF到此处<br>或点击选择文件</p>
                    <div class="upload-btn">选择文件</div>
                    <input type="file" id="fileInput" accept="image/*" style="display: none;">
                </div>
            </div>
            
            <!-- 一键隐藏外框和图片按钮 -->
            <div class="control-group">
                <button id="toggleMediaBtn" style="background: var(--secondary); padding: 8px 0; border-radius: 15px; border: none; color: white; cursor: pointer; font-weight: bold;">
                    隐藏外框和图片
                </button>
            </div>
            
            <div class="obs-tips">
                <h4>OBS使用提示：</h4>
                <p>1. 在OBS中添加<b>浏览器源</b>，输入此页面URL</p>
                <p>2. 设置自定义CSS：<code>body { background-color: transparent !important; }</code></p>
                <p>3. 通过URL参数设置初始透明度：<code>?opacity=50</code></p>
                <p>4. 左下角媒体区域支持图片和GIF</p>
                <p>5. 使用"隐藏外框和图片"按钮可快速隐藏媒体</p>
            </div>
        </div>
        
        <!-- 连接状态指示 -->
        <div class="connection-status">
            <span>API状态: </span>
            <span id="apiStatus">初始化中...</span>
        </div>
        
        <!-- 媒体显示区域 -->
        <div class="media-container" id="mediaContainer">
            <img id="customMedia" src="" alt="自定义媒体">
            <div class="media-controls">
                <button id="mediaHideBtn">隐藏</button>
            </div>
        </div>
    </div>

    <script>
        // API端点配置
        const API_BASE = 'http://127.0.0.1:9780/openapi';
        const PLAYLIST_API = `${API_BASE}/music/play/list`;
        const STATUS_API = `${API_BASE}/music/play/status`;
        const PLAYLIST_WS = 'ws://127.0.0.1:9780/openapi/music/list/ws';
        const PROGRESS_WS = 'ws://127.0.0.1:9780/openapi/music/process/ws';
        
        // DOM元素
        const playlistElement = document.getElementById('playlist');
        const currentSongTitle = document.getElementById('currentSongTitle');
        const currentSongArtist = document.getElementById('currentSongArtist');
        const previousLine = document.getElementById('previousLine');
        const currentLine = document.getElementById('currentLine');
        const nextLine = document.getElementById('nextLine');
        const progressBar = document.getElementById('progressBar');
        const currentTimeEl = document.getElementById('currentTime');
        const totalTimeEl = document.getElementById('totalTime');
        const progressTimeEl = document.getElementById('progressTime');
        const remainingTimeEl = document.getElementById('remainingTime');
        const statusText = document.getElementById('statusText');
        const statusDot = document.getElementById('statusDot');
        const apiStatus = document.getElementById('apiStatus');
        const audioSpectrum = document.getElementById('audioSpectrum');
        const opacitySlider = document.getElementById('opacitySlider');
        const opacityValue = document.getElementById('opacityValue');
        const spectrumSlider = document.getElementById('spectrumSlider');
        const spectrumValue = document.getElementById('spectrumValue');
        const closePanel = document.getElementById('closePanel');
        const spectrumModeBtns = document.querySelectorAll('.spectrum-mode-btn');
        const mediaContainer = document.getElementById('mediaContainer');
        const customMedia = document.getElementById('customMedia');
        const mediaUrlInput = document.getElementById('mediaUrlInput');
        const loadMediaBtn = document.getElementById('loadMediaBtn');
        const clearMediaBtn = document.getElementById('clearMediaBtn');
        const mediaWidthSlider = document.getElementById('mediaWidthSlider');
        const mediaHeightSlider = document.getElementById('mediaHeightSlider');
        const mediaWidthValue = document.getElementById('mediaWidthValue');
        const mediaHeightValue = document.getElementById('mediaHeightValue');
        const mediaHideBtn = document.getElementById('mediaHideBtn');
        const frameToggle = document.getElementById('frameToggle');
        const mainTitle = document.getElementById('mainTitle');
        const uploadArea = document.getElementById('uploadArea');
        const fileInput = document.getElementById('fileInput');
        const toggleMediaBtn = document.getElementById('toggleMediaBtn');
        
        // 状态变量
        let playlist = [];
        let currentSong = null;
        let currentSongId = null;
        let lyrics = [];
        let currentLyricIndex = 0;
        let playlistWS = null;
        let progressWS = null;
        let spectrumCtx = null;
        let spectrumMode = 'bars';
        let spectrumIntensity = 0.7;
        let animationId = null;
        let connectionStatus = {
            playlistAPI: false,
            statusAPI: false,
            playlistWS: false,
            progressWS: false
        };
        let isMediaHidden = false;
        let isMediaVisible = true; // 用于跟踪外框和图片的可见状态
        
        // 更新连接状态显示
        function updateConnectionStatus() {
            const connected = Object.values(connectionStatus).every(status => status);
            statusDot.style.background = connected ? '#55ff55' : '#ff5555';
            statusDot.style.boxShadow = connected ? '0 0 12px #55ff55' : '0 0 12px #ff5555';
            statusText.textContent = connected ? '已连接' : '连接中...';
            
            // 更新API状态
            apiStatus.textContent = `播放列表: ${connectionStatus.playlistAPI ? '✓' : '✗'} | 状态: ${connectionStatus.statusAPI ? '✓' : '✗'} | WS列表: ${connectionStatus.playlistWS ? '✓' : '✗'} | WS进度: ${connectionStatus.progressWS ? '✓' : '✗'}`;
        }
        
        // 创建轻量级粒子
        function createParticle() {
            // 只创建少量粒子（3-5个）
            const particleCount = 3 + Math.floor(Math.random() * 3);
            
            for (let i = 0; i < particleCount; i++) {
                const particle = document.createElement('div');
                particle.className = 'particle';
                
                // 随机大小
                const size = 2 + Math.random() * 3;
                
                // 随机颜色
                const colors = ['#ff5555', '#55ff55', '#5555ff', '#ffff55', '#ff55ff', '#55ffff'];
                const color = colors[Math.floor(Math.random() * colors.length)];
                
                // 随机位置
                const x = Math.random() * window.innerWidth;
                const y = Math.random() * window.innerHeight;
                
                particle.style.left = `${x}px`;
                particle.style.top = `${y}px`;
                particle.style.width = `${size}px`;
                particle.style.height = `${size}px`;
                particle.style.background = color;
                particle.style.boxShadow = `0 0 ${size*2}px ${color}`;
                
                // 随机动画延迟和持续时间
                const delay = Math.random() * 2;
                const duration = 5 + Math.random() * 3;
                particle.style.animationDelay = `${delay}s`;
                particle.style.animationDuration = `${duration}s`;
                
                document.body.appendChild(particle);
                
                // 粒子消失后移除
                setTimeout(() => {
                    if (particle.parentNode) {
                        particle.remove();
                    }
                }, duration * 1000);
            }
        }
        
        // 初始化函数
        async function init() {
            // 初始连接状态
            updateConnectionStatus();
            
            try {
                // 获取播放列表
                await fetchPlaylist();
                
                // 获取当前播放状态
                await fetchCurrentStatus();
                
                // 连接WebSocket
                connectWebSockets();
                
                // 添加少量粒子
                createParticle();
                setInterval(createParticle, 3000);
            } catch (error) {
                console.error('初始化失败:', error);
                statusText.textContent = '连接失败';
                statusDot.style.background = '#ff5555';
                statusDot.style.boxShadow = '0 0 12px #ff5555';
            }
            
            // 设置定时器定期更新状态
            setInterval(fetchCurrentStatus, 5000);
            
            // 初始化频谱Canvas
            initSpectrumCanvas();
            
            // 初始化频谱模拟
            simulateSpectrum();
            
            // 初始化控制面板
            initControlPanel();
            
            // 初始化媒体控制
            initMediaControls();
            
            // 从URL参数获取初始透明度
            const urlParams = new URLSearchParams(window.location.search);
            const initialOpacity = urlParams.get('opacity');
            if (initialOpacity !== null) {
                const opacity = parseInt(initialOpacity);
                if (!isNaN(opacity) && opacity >= 0 && opacity <= 100) {
                    setBackgroundOpacity(opacity);
                    opacitySlider.value = opacity;
                    opacityValue.textContent = `${opacity}%`;
                }
            }
            
            // 检查标题长度并调整滚动效果
            adjustTitleScroll();
        }
        
        // 调整标题滚动效果
        function adjustTitleScroll() {
            const titleText = mainTitle.textContent;
            if (titleText.length <= 12) {
                mainTitle.classList.add('no-scroll');
            } else {
                mainTitle.classList.remove('no-scroll');
            }
        }
        
        // 初始化频谱Canvas
        function initSpectrumCanvas() {
            const container = document.querySelector('.audio-spectrum-container');
            if (!container) return;
            
            const width = container.clientWidth;
            const height = container.clientHeight;
            
            audioSpectrum.width = width;
            audioSpectrum.height = height;
            
            spectrumCtx = audioSpectrum.getContext('2d');
        }
        
        // 模拟频谱
        function simulateSpectrum() {
            if (animationId) {
                cancelAnimationFrame(animationId);
            }
            
            const draw = () => {
                if (!spectrumCtx) return;
                
                const width = audioSpectrum.width;
                const height = audioSpectrum.height;
                
                // 清除画布
                spectrumCtx.clearRect(0, 0, width, height);
                
                // 生成模拟频谱数据
                const bufferLength = 64;
                const dataArray = new Uint8Array(bufferLength);
                
                for (let i = 0; i < bufferLength; i++) {
                    // 生成基于时间和频率的模拟值
                    const time = Date.now() * 0.002;
                    const value = Math.sin(time + i * 0.2) * 0.5 + 0.5;
                    const scaledValue = value * 150 * spectrumIntensity + 10;
                    dataArray[i] = Math.min(255, scaledValue);
                }
                
                // 根据模式绘制频谱
                switch (spectrumMode) {
                    case 'bars':
                        drawBars(dataArray, width, height);
                        break;
                    case 'wave':
                        drawWave(dataArray, width, height);
                        break;
                    case 'circle':
                        drawCircle(dataArray, width, height);
                        break;
                }
                
                animationId = requestAnimationFrame(draw);
            };
            
            animationId = requestAnimationFrame(draw);
        }
        
        // 绘制柱状频谱
        function drawBars(dataArray, width, height) {
            const barCount = dataArray.length;
            const barWidth = (width / barCount) * 1.5;
            const barSpacing = barWidth * 0.3;
            const maxBarHeight = height * 0.8;
            
            for (let i = 0; i < barCount; i++) {
                const value = dataArray[i];
                const barHeight = (value / 255) * maxBarHeight * spectrumIntensity;
                const x = i * (barWidth + barSpacing);
                const y = height - barHeight;
                
                // 创建渐变
                const gradient = spectrumCtx.createLinearGradient(0, y, 0, height);
                gradient.addColorStop(0, `hsl(${200 + value / 2}, 100%, 70%)`);
                gradient.addColorStop(1, `hsl(${300 + value / 3}, 100%, 50%)`);
                
                spectrumCtx.fillStyle = gradient;
                spectrumCtx.fillRect(x, y, barWidth, barHeight);
                
                // 添加顶部发光效果
                spectrumCtx.beginPath();
                spectrumCtx.rect(x, y, barWidth, 2);
                spectrumCtx.fillStyle = 'rgba(255, 255, 255, 0.8)';
                spectrumCtx.fill();
            }
        }
        
        // 绘制波浪频谱
        function drawWave(dataArray, width, height) {
            const centerY = height / 2;
            const maxAmplitude = height * 0.4 * spectrumIntensity;
            const pointSpacing = width / (dataArray.length - 1);
            
            spectrumCtx.beginPath();
            spectrumCtx.moveTo(0, centerY);
            
            for (let i = 0; i < dataArray.length; i++) {
                const value = dataArray[i];
                const amplitude = (value / 255) * maxAmplitude;
                const x = i * pointSpacing;
                const y = centerY + amplitude * Math.sin(i * 0.2 + Date.now() * 0.002);
                
                if (i === 0) {
                    spectrumCtx.moveTo(x, y);
                } else {
                    spectrumCtx.lineTo(x, y);
                }
            }
            
            // 创建渐变描边
            const gradient = spectrumCtx.createLinearGradient(0, 0, width, 0);
            gradient.addColorStop(0, '#ff00cc');
            gradient.addColorStop(0.5, '#00ccff');
            gradient.addColorStop(1, '#ffff00');
            
            spectrumCtx.strokeStyle = gradient;
            spectrumCtx.lineWidth = 3;
            spectrumCtx.stroke();
            
            // 添加发光效果
            spectrumCtx.shadowColor = '#00ffff';
            spectrumCtx.shadowBlur = 15;
            spectrumCtx.stroke();
            spectrumCtx.shadowBlur = 0;
            
            // 填充波浪
            spectrumCtx.lineTo(width, height);
            spectrumCtx.lineTo(0, height);
            spectrumCtx.closePath();
            
            const fillGradient = spectrumCtx.createLinearGradient(0, centerY, 0, height);
            fillGradient.addColorStop(0, 'rgba(255, 0, 204, 0.3)');
            fillGradient.addColorStop(1, 'rgba(0, 204, 255, 0.1)');
            
            spectrumCtx.fillStyle = fillGradient;
            spectrumCtx.fill();
        }
        
        // 绘制圆形频谱
        function drawCircle(dataArray, width, height) {
            const centerX = width / 2;
            const centerY = height / 2;
            const maxRadius = Math.min(width, height) * 0.4;
            const minRadius = maxRadius * 0.3;
            const pointCount = dataArray.length;
            const angleStep = (Math.PI * 2) / pointCount;
            
            spectrumCtx.beginPath();
            
            for (let i = 0; i <= pointCount; i++) {
                const value = dataArray[i % pointCount];
                const radius = minRadius + (value / 255) * (maxRadius - minRadius) * spectrumIntensity;
                const angle = i * angleStep;
                const x = centerX + Math.cos(angle) * radius;
                const y = centerY + Math.sin(angle) * radius;
                
                if (i === 0) {
                    spectrumCtx.moveTo(x, y);
                } else {
                    spectrumCtx.lineTo(x, y);
                }
            }
            
            spectrumCtx.closePath();
            
            // 创建渐变填充
            const gradient = spectrumCtx.createRadialGradient(
                centerX, centerY, minRadius,
                centerX, centerY, maxRadius
            );
            gradient.addColorStop(0, 'rgba(255, 0, 204, 0.8)');
            gradient.addColorStop(1, 'rgba(0, 204, 255, 0.3)');
            
            spectrumCtx.fillStyle = gradient;
            spectrumCtx.fill();
            
            // 添加描边
            spectrumCtx.strokeStyle = '#00ffff';
            spectrumCtx.lineWidth = 2;
            spectrumCtx.stroke();
            
            // 添加中心点
            spectrumCtx.beginPath();
            spectrumCtx.arc(centerX, centerY, 5, 0, Math.PI * 2);
            spectrumCtx.fillStyle = '#ffffff';
            spectrumCtx.fill();
            spectrumCtx.shadowColor = '#ffffff';
            spectrumCtx.shadowBlur = 10;
            spectrumCtx.fill();
            spectrumCtx.shadowBlur = 0;
        }
        
        // 初始化控制面板
        function initControlPanel() {
            // 透明度滑块
            opacitySlider.addEventListener('input', function() {
                const opacity = parseInt(this.value);
                setBackgroundOpacity(opacity);
                opacityValue.textContent = `${opacity}%`;
            });
            
            // 频谱强度滑块
            spectrumSlider.addEventListener('input', function() {
                spectrumIntensity = parseInt(this.value) / 100;
                spectrumValue.textContent = `${this.value}%`;
            });
            
            // 关闭面板按钮
            closePanel.addEventListener('click', function() {
                document.querySelector('.controls-panel').style.display = 'none';
            });
            
            // 频谱模式按钮
            spectrumModeBtns.forEach(btn => {
                btn.addEventListener('click', function() {
                    spectrumModeBtns.forEach(b => b.classList.remove('active'));
                    this.classList.add('active');
                    spectrumMode = this.dataset.mode;
                    simulateSpectrum();
                });
            });
        }
        
        // 初始化媒体控制
        function initMediaControls() {
            // 从本地存储加载媒体设置
            const savedMediaUrl = localStorage.getItem('mediaUrl');
            const savedMediaWidth = localStorage.getItem('mediaWidth');
            const savedMediaHeight = localStorage.getItem('mediaHeight');
            const savedMediaHidden = localStorage.getItem('mediaHidden');
            const savedFrameVisible = localStorage.getItem('frameVisible');
            const savedMediaVisible = localStorage.getItem('mediaVisible');
            
            // 设置媒体URL
            if (savedMediaUrl) {
                customMedia.src = savedMediaUrl;
                mediaUrlInput.value = savedMediaUrl;
            }
            
            // 设置媒体尺寸
            if (savedMediaWidth) {
                mediaContainer.style.width = `${savedMediaWidth}px`;
                mediaWidthSlider.value = savedMediaWidth;
                mediaWidthValue.textContent = `${savedMediaWidth}px`;
            }
            if (savedMediaHeight) {
                mediaContainer.style.height = `${savedMediaHeight}px`;
                mediaHeightSlider.value = savedMediaHeight;
                mediaHeightValue.textContent = `${savedMediaHeight}px`;
            }
            
            // 设置隐藏状态
            if (savedMediaHidden === 'true') {
                mediaContainer.style.display = 'none';
                isMediaHidden = true;
                mediaHideBtn.textContent = '显示';
            } else {
                mediaContainer.style.display = 'flex';
                isMediaHidden = false;
                mediaHideBtn.textContent = '隐藏';
            }
            
            // 设置外框显示状态
            if (savedFrameVisible !== null) {
                frameToggle.checked = savedFrameVisible === 'true';
                updateFrameDisplay();
            }
            
            // 设置媒体可见状态
            if (savedMediaVisible !== null) {
                isMediaVisible = savedMediaVisible === 'true';
                updateMediaVisibility();
            }
            
            // 更新外框显示
            function updateFrameDisplay() {
                const isChecked = frameToggle.checked;
                if (isChecked) {
                    mediaContainer.style.border = '2px solid var(--primary)';
                    mediaContainer.style.background = 'rgba(0, 0, 0, 0.6)';
                } else {
                    mediaContainer.style.border = 'none';
                    mediaContainer.style.background = 'transparent';
                }
                // 保存状态
                localStorage.setItem('frameVisible', isChecked);
            }
            
            // 更新媒体可见性
            function updateMediaVisibility() {
                mediaContainer.style.display = isMediaVisible ? 'flex' : 'none';
                toggleMediaBtn.textContent = isMediaVisible ? '隐藏外框和图片' : '显示外框和图片';
                localStorage.setItem('mediaVisible', isMediaVisible);
            }
            
            // 一键隐藏/显示外框和图片
            toggleMediaBtn.addEventListener('click', function() {
                isMediaVisible = !isMediaVisible;
                updateMediaVisibility();
            });
            
            // 加载媒体按钮
            loadMediaBtn.addEventListener('click', function() {
                const mediaUrl = mediaUrlInput.value.trim();
                if (mediaUrl) {
                    customMedia.src = mediaUrl;
                    mediaContainer.style.display = 'flex';
                    isMediaHidden = false;
                    mediaHideBtn.textContent = '隐藏';
                    
                    // 保存到本地存储
                    localStorage.setItem('mediaUrl', mediaUrl);
                    localStorage.setItem('mediaHidden', 'false');
                    
                    // 确保媒体可见
                    isMediaVisible = true;
                    updateMediaVisibility();
                } else {
                    alert('请输入有效的图片/GIF URL');
                }
            });
            
            // 清除媒体按钮
            clearMediaBtn.addEventListener('click', function() {
                customMedia.src = '';
                mediaUrlInput.value = '';
                
                // 清除本地存储
                localStorage.removeItem('mediaUrl');
                
                // 恢复默认位置和大小
                mediaContainer.style.left = '20px';
                mediaContainer.style.bottom = '20px';
                mediaContainer.style.width = '200px';
                mediaContainer.style.height = '150px';
                mediaWidthSlider.value = 200;
                mediaHeightSlider.value = 150;
                mediaWidthValue.textContent = '200px';
                mediaHeightValue.textContent = '150px';
                
                // 确保显示
                mediaContainer.style.display = 'flex';
                isMediaHidden = false;
                mediaHideBtn.textContent = '隐藏';
                
                // 保存默认设置
                localStorage.setItem('mediaWidth', '200');
                localStorage.setItem('mediaHeight', '150');
                localStorage.setItem('mediaHidden', 'false');
                
                // 确保媒体可见
                isMediaVisible = true;
                updateMediaVisibility();
            });
            
            // 媒体宽度滑块
            mediaWidthSlider.addEventListener('input', function() {
                const width = parseInt(this.value);
                mediaContainer.style.width = `${width}px`;
                mediaWidthValue.textContent = `${width}px`;
                localStorage.setItem('mediaWidth', width);
            });
            
            // 媒体高度滑块
            mediaHeightSlider.addEventListener('input', function() {
                const height = parseInt(this.value);
                mediaContainer.style.height = `${height}px`;
                mediaHeightValue.textContent = `${height}px`;
                localStorage.setItem('mediaHeight', height);
            });
            
            // 隐藏媒体按钮
            mediaHideBtn.addEventListener('click', function() {
                mediaContainer.style.display = isMediaHidden ? 'flex' : 'none';
                isMediaHidden = !isMediaHidden;
                mediaHideBtn.textContent = isMediaHidden ? '显示' : '隐藏';
                localStorage.setItem('mediaHidden', isMediaHidden);
            });
            
            // 外框显示开关
            frameToggle.addEventListener('change', updateFrameDisplay);
            
            // 初始化外框显示
            updateFrameDisplay();
            
            // 初始化媒体可见性
            updateMediaVisibility();
            
            // 图片上传功能
            uploadArea.addEventListener('click', function() {
                fileInput.click();
            });
            
            // 拖放上传功能
            uploadArea.addEventListener('dragover', function(e) {
                e.preventDefault();
                uploadArea.style.borderColor = 'var(--primary)';
                uploadArea.style.background = 'rgba(255, 0, 204, 0.2)';
            });
            
            uploadArea.addEventListener('dragleave', function() {
                uploadArea.style.borderColor = 'rgba(255, 255, 255, 0.3)';
                uploadArea.style.background = 'rgba(0, 0, 0, 0.2)';
            });
            
            uploadArea.addEventListener('drop', function(e) {
                e.preventDefault();
                uploadArea.style.borderColor = 'rgba(255, 255, 255, 0.3)';
                uploadArea.style.background = 'rgba(0, 0, 0, 0.2)';
                
                if (e.dataTransfer.files.length) {
                    const file = e.dataTransfer.files[0];
                    handleFileUpload(file);
                }
            });
            
            fileInput.addEventListener('change', function() {
                if (this.files.length) {
                    const file = this.files[0];
                    handleFileUpload(file);
                }
            });
            
            // 处理文件上传
            function handleFileUpload(file) {
                if (!file.type.match('image.*')) {
                    alert('请上传图片或GIF文件');
                    return;
                }
                
                const reader = new FileReader();
                reader.onload = function(e) {
                    customMedia.src = e.target.result;
                    mediaUrlInput.value = e.target.result;
                    
                    // 保存到本地存储
                    localStorage.setItem('mediaUrl', e.target.result);
                    localStorage.setItem('mediaHidden', 'false');
                    
                    // 显示媒体容器
                    mediaContainer.style.display = 'flex';
                    isMediaHidden = false;
                    mediaHideBtn.textContent = '隐藏';
                    
                    // 确保媒体可见
                    isMediaVisible = true;
                    updateMediaVisibility();
                    
                    // 提示上传成功
                    alert('图片上传成功！');
                };
                reader.readAsDataURL(file);
            }
        }
        
        // 设置背景透明度
        function setBackgroundOpacity(opacity) {
            const opacityValue = opacity / 100;
            document.documentElement.style.setProperty('--bg-opacity', opacityValue);
        }
        
        // 获取播放列表
        async function fetchPlaylist() {
            try {
                const response = await fetch(PLAYLIST_API);
                if (!response.ok) {
                    throw new Error(`HTTP错误! 状态: ${response.status}`);
                }
                
                const data = await response.json();
                console.log('播放列表数据:', data);
                
                // 根据API返回格式处理数据
                if (data.code === 0 && data.data && Array.isArray(data.data)) {
                    playlist = data.data;
                    connectionStatus.playlistAPI = true;
                    renderPlaylist();
                    
                    // 如果当前没有设置歌曲，使用第一首作为默认
                    if (playlist.length > 0 && !currentSong) {
                        currentSong = playlist[0];
                        currentSongId = playlist[0]._id || playlist[0].id;
                        updateCurrentSongInfo();
                    }
                } else {
                    throw new Error('播放列表数据格式错误');
                }
            } catch (error) {
                console.error('获取播放列表失败:', error);
                connectionStatus.playlistAPI = false;
                
                // 显示错误状态
                playlistElement.innerHTML = `
                    <li class="playlist-item">
                        <div class="song-number">!</div>
                        <div class="song-info">
                            <div class="song-title">无法加载播放列表</div>
                            <div class="song-artist">${error.message}</div>
                        </div>
                        <div class="song-duration">-:-</div>
                    </li>
                `;
            } finally {
                updateConnectionStatus();
            }
        }
        
        // 获取当前播放状态
        async function fetchCurrentStatus() {
            try {
                const response = await fetch(STATUS_API);
                if (!response.ok) {
                    throw new Error(`HTTP错误! 状态: ${response.status}`);
                }
                
                const statusData = await response.json();
                console.log('播放状态数据:', statusData);
                
                // 根据API返回格式处理数据
                if (statusData.code === 0 && statusData.data) {
                    connectionStatus.statusAPI = true;
                    
                    // 更新当前歌曲ID
                    if (statusData.data.songId) {
                        currentSongId = statusData.data.songId;
                        
                        // 在播放列表中查找当前歌曲
                        const newCurrentSong = playlist.find(song => 
                            song._id === currentSongId || 
                            song.id === currentSongId ||
                            song.songId === currentSongId
                        );
                        
                        if (newCurrentSong) {
                            currentSong = newCurrentSong;
                            updateCurrentSongInfo();
                        }
                    }
                    
                    updateLyricsDisplay(statusData.data);
                } else {
                    throw new Error('播放状态数据格式错误');
                }
            } catch (error) {
                console.error('获取播放状态失败:', error);
                connectionStatus.statusAPI = false;
                
                // 显示错误状态
                currentSongTitle.textContent = "无法获取歌曲信息";
                currentSongArtist.textContent = error.message;
                currentLine.textContent = "歌词服务不可用";
            } finally {
                updateConnectionStatus();
            }
        }
        
        // 渲染播放列表
        function renderPlaylist() {
            playlistElement.innerHTML = '';
            
            if (!playlist || playlist.length === 0) {
                playlistElement.innerHTML = `
                    <li class="playlist-item">
                        <div class="song-number">-</div>
                        <div class="song-info">
                            <div class="song-title">播放列表为空</div>
                            <div class="song-artist">请添加歌曲</div>
                        </div>
                        <div class="song-duration">0:00</div>
                    </li>
                `;
                return;
            }
            
            playlist.forEach((song, index) => {
                const li = document.createElement('li');
                li.className = 'playlist-item';
                
                // 检查是否是当前歌曲
                const songId = song._id || song.id || song.songId;
                const isActive = currentSongId && songId === currentSongId;
                
                if (isActive) {
                    li.classList.add('active');
                    currentSong = song;
                }
                
                // 确保歌曲信息存在
                const title = song.name || song.title || "未知歌曲";
                const artist = song.artist || song.singer || "未知艺术家";
                const duration = song.time || song.duration || "0:00";
                
                li.innerHTML = `
                    <div class="song-number">${index + 1}</div>
                    <div class="song-info">
                        <div class="song-title" title="${title}">${title.length > 15 ? title.substring(0, 15) + '...' : title}</div>
                        <div class="song-artist" title="${artist}">${artist.length > 20 ? artist.substring(0, 20) + '...' : artist}</div>
                    </div>
                    <div class="song-duration">${duration}</div>
                `;
                
                // 点击歌曲播放
                li.addEventListener('click', () => {
                    currentSongId = songId;
                    currentSong = song;
                    updateCurrentSongInfo();
                    renderPlaylist();
                });
                
                playlistElement.appendChild(li);
            });
        }
        
        // 更新当前歌曲信息
        function updateCurrentSongInfo() {
            if (!currentSong) {
                currentSongTitle.textContent = "未播放歌曲";
                currentSongArtist.textContent = "等待播放...";
                totalTimeEl.textContent = "0:00";
                return;
            }
            
            // 确保歌曲信息存在
            const title = currentSong.name || currentSong.title || '未知歌曲';
            const artist = currentSong.artist || currentSong.singer || '未知艺术家';
            
            currentSongTitle.textContent = title.length > 25 ? title.substring(0, 25) + '...' : title;
            currentSongTitle.title = title;
            
            currentSongArtist.textContent = artist.length > 30 ? artist.substring(0, 30) + '...' : artist;
            currentSongArtist.title = artist;
            
            // 从播放状态获取总时长，如果没有则使用歌曲的time字段
            const totalDuration = currentSong.time || currentSong.duration || "0:00";
            totalTimeEl.textContent = totalDuration;
            
            // 更新专辑封面
            const albumArt = document.querySelector('.album-art');
            if (currentSong.cover) {
                albumArt.innerHTML = `<img src="${currentSong.cover}" alt="专辑封面">`;
            } else {
                albumArt.innerHTML = '<div>♪</div>';
            }
        }
        
        // 更新歌词显示
        function updateLyricsDisplay(status) {
            // 确保当前歌曲存在
            if (!currentSong) {
                previousLine.textContent = "";
                currentLine.textContent = "等待歌曲信息...";
                nextLine.textContent = "";
                return;
            }
            
            // 获取歌词数组
            lyrics = currentSong.lyric || currentSong.lyrics || [];
            
            // 找到当前歌词索引
            const currentTime = status.currentTime || 0;
            let newIndex = 0;
            
            for (let i = 0; i < lyrics.length; i++) {
                if (lyrics[i].time <= currentTime) {
                    newIndex = i;
                } else {
                    break;
                }
            }
            
            // 更新显示
            if (newIndex !== currentLyricIndex || !lyrics[currentLyricIndex]) {
                currentLyricIndex = newIndex;
                
                previousLine.textContent = currentLyricIndex > 0 ? lyrics[currentLyricIndex - 1].lineLyric : '';
                currentLine.textContent = lyrics[currentLyricIndex]?.lineLyric || '当前歌词';
                nextLine.textContent = currentLyricIndex < lyrics.length - 1 ? lyrics[currentLyricIndex + 1].lineLyric : '';
            }
            
            // 更新进度条
            const duration = status.duration || parseDuration(currentSong.time || "0:00");
            const progress = duration > 0 ? (currentTime / duration) * 100 : 0;
            progressBar.style.width = `${progress}%`;
            
            // 更新时间显示
            const remaining = duration - currentTime;
            currentTimeEl.textContent = formatTime(currentTime);
            progressTimeEl.textContent = formatTime(currentTime);
            remainingTimeEl.textContent = `-${formatTime(remaining)}`;
            
            // 添加少量粒子效果
            createParticle();
        }
        
        // 辅助函数：将"分:秒"格式转换为秒数
        function parseDuration(timeStr) {
            if (!timeStr) return 0;
            
            const parts = timeStr.split(':');
            if (parts.length < 2) return 0;
            
            const minutes = parseInt(parts[0]) || 0;
            const seconds = parseInt(parts[1]) || 0;
            
            return minutes * 60 + seconds;
        }
        
        // 辅助函数：格式化时间
        function formatTime(seconds) {
            if (isNaN(seconds)) return "0:00";
            
            const mins = Math.floor(seconds / 60);
            const secs = Math.floor(seconds % 60);
            return `${mins}:${secs < 10 ? '0' : ''}${secs}`;
        }
        
        // 连接WebSocket
        function connectWebSockets() {
            // 播放列表WebSocket
            playlistWS = new WebSocket(PLAYLIST_WS);
            
            playlistWS.onopen = () => {
                connectionStatus.playlistWS = true;
                updateConnectionStatus();
            };
            
            playlistWS.onmessage = (event) => {
                try {
                    const data = JSON.parse(event.data);
                    playlist = data;
                    
                    // 尝试保持当前歌曲选择
                    if (currentSongId) {
                        const song = playlist.find(song => 
                            song._id === currentSongId || 
                            song.id === currentSongId ||
                            song.songId === currentSongId
                        );
                        
                        if (song) {
                            currentSong = song;
                        } else if (playlist.length > 0) {
                            currentSong = playlist[0];
                            currentSongId = playlist[0]._id || playlist[0].id;
                        }
                    }
                    
                    renderPlaylist();
                    updateCurrentSongInfo();
                } catch (error) {
                    console.error('播放列表WebSocket消息解析失败:', error);
                }
            };
            
            playlistWS.onerror = (error) => {
                connectionStatus.playlistWS = false;
                updateConnectionStatus();
            };
            
            playlistWS.onclose = () => {
                connectionStatus.playlistWS = false;
                updateConnectionStatus();
                // 尝试重新连接
                setTimeout(connectWebSockets, 5000);
            };
            
            // 进度WebSocket
            progressWS = new WebSocket(PROGRESS_WS);
            
            progressWS.onopen = () => {
                connectionStatus.progressWS = true;
                updateConnectionStatus();
            };
            
            progressWS.onmessage = (event) => {
                try {
                    const progress = JSON.parse(event.data);
                    updateLyricsDisplay({
                        currentTime: progress.currentTime,
                        duration: progress.duration
                    });
                } catch (error) {
                    console.error('进度WebSocket消息解析失败:', error);
                }
            };
            
            progressWS.onerror = (error) => {
                connectionStatus.progressWS = false;
                updateConnectionStatus();
            };
            
            progressWS.onclose = () => {
                connectionStatus.progressWS = false;
                updateConnectionStatus();
                // 尝试重新连接
                setTimeout(connectWebSockets, 5000);
            };
        }
        
        // 初始化应用
        window.addEventListener('DOMContentLoaded', init);
        
        // 窗口大小变化时重新初始化Canvas
        window.addEventListener('resize', function() {
            initSpectrumCanvas();
            simulateSpectrum();
        });
    </script>
</body>
</html>